﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using DataViews.Messages;
using DataViews.Models;
using DataViews.Tools;
using DataViews.Views;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;

namespace DataViews.ViewModels
{
    public partial class DataListViewModel<T> :  ObservableObject,IContext
    {
        [ObservableProperty]
        bool allItemsSelected = false;

        [ObservableProperty]
        ObservableCollection<DisplayField> displayFields = new ObservableCollection<DisplayField>();
       

        [ObservableProperty]
        ObservableCollection<T> dataItems = new ObservableCollection<T>();

        [ObservableProperty]
        ObservableCollection<T> selectedDataItems = new ObservableCollection<T>();

        [ObservableProperty]
        IQueryable<T> currentQuery = null;

        [ObservableProperty]
        IQueryable<T> sourceQuery = null;

        [ObservableProperty]
        ObservableCollection<FilterItem> filters = new ObservableCollection<FilterItem>();


        [ObservableProperty]
        int totalItemCount = 0;
        [ObservableProperty]
        int totalPageCount = 0;
        [ObservableProperty]
        int currentPageFromOne = 0;
        [ObservableProperty]
        int currentCountInPage = 0;
        [ObservableProperty]
        int displayCountPerPage = 100;
        [ObservableProperty]
        int? pageToGo = null;

        public string Context { get; set; }        

        public DataListViewModel(string context, ObservableCollection<DisplayField> displayFields, IQueryable<T> sourceQuery, int displayCountPerPage)
        {
            Context = context;
            DisplayFields = displayFields;
            SourceQuery = sourceQuery;
            DisplayCountPerPage = displayCountPerPage;

            //
            this.PropertyChanged += ((o, e) => {
                if (e.PropertyName == "AllItemsSelected")
                {
                    WeakReferenceMessenger.Default.Send<SelectAllMessage>(new SelectAllMessage(Context, AllItemsSelected, DataItems));

                }
                else if (e.PropertyName == "CurrentQuery")
                {
                    TotalItemCount = 0;
                    TotalPageCount = 0;
                    CurrentPageFromOne = 1;
                    CurrentCountInPage = 0;
                    DataItems.Clear();
                    SelectedDataItems.Clear();
                    if (CurrentQuery != null)
                    {
                        TotalItemCount = CurrentQuery.Count();
                        TotalPageCount = TotalItemCount / DisplayCountPerPage + (TotalItemCount % DisplayCountPerPage > 0 ? 1 : 0);
                        CurrentPageFromOne = 1;
                        _GetCurrentPageItems();
                    }
                }
                else if (e.PropertyName == "CurrentPageFromOne")
                {
                    _GetCurrentPageItems();
                }
            });

            ////注意：用Task.Run不行
            //ThreadPool.QueueUserWorkItem(delegate
            //{
            //    SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(System.Windows.Application.Current.Dispatcher));
            //    SynchronizationContext.Current!.Post(pl =>
            //    {
            //        //里面写真正的业务内容
            //        DoQuery();
            //    }, null);
            //});


            Application.Current.Dispatcher.Invoke(() =>
            {
                DoQuery();
            });


            WeakReferenceMessenger.Default.Register<SortedHeaderClickMessage>(this, (r, e) => {

                if (e.Context != Context)
                {
                    return;
                }

                //
                var dispaly_item = e.FieldClicked;

                foreach (var item in DisplayFields)
                {
                    if (dispaly_item != item)
                    {
                        item.OrderBy = "";
                    }
                    else
                    {
                        if (item.OrderBy == "↑")
                        {
                            item.OrderBy = "↓";
                        }
                        else
                        {
                            item.OrderBy = "↑";
                        }

                        CurrentQuery = DBTool.OrderyBy(CurrentQuery, item.FieldName!, item.OrderBy == "↑" ? true : false);//"↑"=降序  "↓"=升序 注意：从表头看上下箭头

                    }
                }


            });

            WeakReferenceMessenger.Default.Register<DoFilterMessage>(this, (r, e) => {
                if (e.Context != Context)
                {
                    return;
                }

                //
                Filters = e.Filters;
                DoQuery();
            });

            WeakReferenceMessenger.Default.Register<SelectionChangedMessage>(this, (r, e) => {
                if (e.Context != Context)
                {
                    return;
                }

                //
                SelectedDataItems.Clear();

                foreach (var item in e.SelectedItems)
                {
                    SelectedDataItems.Add((T)item);
                }
            });

        }

        void _GetCurrentPageItems()
        {
            DataItems.Clear();
            SelectedDataItems.Clear();

            //根据当前页号计算需要跳过多少，取多少
            int skip = DisplayCountPerPage * (CurrentPageFromOne - 1);
            int remain = CurrentQuery.Count() - skip;
            int take = DisplayCountPerPage <= remain ? DisplayCountPerPage : remain;
            var q = CurrentQuery.Skip(skip).Take(take);



            foreach (var item in q)
            {
                DataItems.Add(item);
            }

            //更新当前页面条数
            CurrentCountInPage = DataItems.Count;


        }

        [RelayCommand]      
        void DoQuery()
        {
            var order_item = DisplayFields.Where(x => x.OrderBy != "").FirstOrDefault();
            string order_filed = "";
            bool order_desc = false;
            if (order_item == null)
            {
                DisplayFields[0].OrderBy = "↑";
                order_item = DisplayFields[0];
            }
            order_filed = order_item.FieldName!;
            order_desc = order_item.OrderBy == "↑" ? true : false;//""=不排序  "↑"=降序  "↓"=升序 注意：从表头看上下箭头

            //注：调用泛型方法不能直接 CurrentQuery = DBTool.DoQuery<T>(SourceQuery, Filters, order_filed, order_desc);
            //                          T在此须为给定的类
            var method_info=typeof(DBTool).GetMethod("DoQuery")!;
            var generic_method=method_info.MakeGenericMethod(typeof(T));
            CurrentQuery = (generic_method!.Invoke(null, new object[] { SourceQuery, Filters, order_filed, order_desc }) as IQueryable<T>)!;
            
        }


        [RelayCommand]
        void PageAddOne()
        {
            if (CurrentPageFromOne < TotalPageCount)
            {
                CurrentPageFromOne++;
            }
            else
            {
                Serilog.Log.Information("【提示】已经是最大页数");
            }
        }

        [RelayCommand]
        void PageSubOne()
        {
            if (CurrentPageFromOne > 1)
            {
                CurrentPageFromOne--;
            }
            else
            {
                Serilog.Log.Information("【提示】已经是最小页数");
            }
        }

        [RelayCommand]
        void PageGoto()
        {
            if (PageToGo == null)
            {
                return;
            }

            if (PageToGo.Value >= 1 && PageToGo.Value <= TotalPageCount)
            {
                CurrentPageFromOne = PageToGo.Value;
            }
            else
            {
                Serilog.Log.Information($"【提示】页数应该在[1,{TotalPageCount}]范围内");
            }
        }

    }
}
